package com.jy.datapipeline.importserver.support;

import com.jy.datapipeline.common.constants.CtlContentConstants;
import com.jy.datapipeline.common.constants.PrefixConstants;
import com.jy.datapipeline.importserver.common.enums.impl.*;
import com.jy.datapipeline.common.exception.GlobalException;
import com.jy.datapipeline.common.util.DateTimeUtil;
import com.jy.datapipeline.common.util.SnowFlakeUtil;
import com.jy.datapipeline.common.util.StringUtil;
import com.jy.datapipeline.importserver.entity.ImportRule;
import com.jy.datapipeline.importserver.entity.ImportRuleTable;
import com.jy.datapipeline.importserver.entity.ImportSubtask;
import com.mysql.cj.util.StringUtils;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Date;

/**
 * @类名 ImportTaskSupport
 * @描述 TODO
 * @作者 白条君
 * @创建日期 2023/4/28 18:19
 * @版本 1.0
 */
@Component
public class ImportSubtaskSupport {

    public ImportSubtask createSubTask(Date nextStartTime,
                                       String taskId,
                                       ImportRuleTable importRuleTable,
                                       String sourceTableName,
                                       String businessName,
                                       String dataCircle,
                                       Date dataCircleTime,
                                       ImportRule importRule,
                                       String targetColumnList,
                                       String storeLocation) throws GlobalException {
        ImportSubtask importSubTask = new ImportSubtask();
        importSubTask.setSubtaskId(StringUtil.concat(new StringBuffer(), PrefixConstants.SUBTASK_PREFIX, "_", String.valueOf(SnowFlakeUtil.getNextId())));
        importSubTask.setSqlldrInfoId(importRule.getSqlldrInfoId());
        importSubTask.setTaskId(taskId);
        importSubTask.setRuleTableId(importRuleTable.getRuleTableId());
        importSubTask.setCircleTime(dataCircleTime);
        //创建并添加文件名称
        String sourceDatabase = importRuleTable.getSourceDatabase();
        String sourceSchema = importRuleTable.getSourceSchema();
        String cityCode = importRuleTable.getCityCode();
        //生成文件名称
        String fileName = this.generateFileName(cityCode, sourceDatabase, sourceSchema, sourceTableName, businessName, dataCircle, storeLocation);
        importSubTask.setFileName(fileName);
        //初始化重拾次数
        importSubTask.setTryCount(0);
        //创建并添加ctl内容
        String ctlFileContent = this.generateCtlContext(nextStartTime, importRuleTable, importRule, targetColumnList);
        importSubTask.setCtlContext(ctlFileContent);
        //初始化子任务执行状态为未开始
        importSubTask.setSubtaskStatus(String.valueOf(TaskStatusEnum.NOT_START.getCode()));
        return importSubTask;
    }

    public String generateFileName(String cityCode,
                                    String sourceDatabase,
                                    String sourceSchema,
                                    String sourceTableName,
                                    String businessName,
                                    String dataCircle,
                                    String storeLocation) {
        //构建文件名称
        String fileName;
        if (!StringUtils.isNullOrEmpty(cityCode) && StringUtils.isNullOrEmpty(businessName)) {
            fileName = StringUtil.concat(new StringBuffer(),
                    storeLocation + "/" + sourceDatabase, "_", sourceSchema, "_", sourceTableName, "_", cityCode, "_", dataCircle, ".verf");
        } else if (!StringUtils.isNullOrEmpty(cityCode) && !StringUtils.isNullOrEmpty(businessName)) {
            fileName = StringUtil.concat(new StringBuffer(),
                    storeLocation + "/" + sourceDatabase, "_", sourceSchema, "_", sourceTableName, "_", cityCode, "_", businessName, "_", dataCircle, ".verf");
        } else if (StringUtils.isNullOrEmpty(cityCode) && !StringUtils.isNullOrEmpty(businessName)) {
            fileName = StringUtil.concat(new StringBuffer(),
                    storeLocation + "/" + sourceDatabase, "_", sourceSchema, "_", sourceTableName, "_", businessName, "_", dataCircle, ".verf");
        } else {
            fileName = StringUtil.concat(new StringBuffer(),
                    storeLocation + "/" + sourceDatabase, "_", sourceSchema, "_", sourceTableName, "_", dataCircle, ".verf");
        }

        return fileName;
    }

    public String generateCtlContext(Date nextStartTime,
                                      ImportRuleTable importRuleTable,
                                      ImportRule importRule,
                                      String targetColumnList) throws GlobalException {
        String dynamicTableRule = importRuleTable.getDynamicTableRule();
        String isDynamicTable = importRuleTable.getIsDynamicTable();
        String content = CtlContentConstants.CTL_CONTENT;
        //目标表
        if (String.valueOf(DynamicTableEnum.DYNAMIC.getCode()).equals(isDynamicTable)) {
            Integer value = importRuleTable.getDynamicTableRuleValue();
            String dataCircle = null;
            //计算表规则
            if (DynamicTableRuleEnum.ADDMONTHS.getMsg().equals(dynamicTableRule)) {
                String dataIntervalUnit = String.valueOf(DataIntervalUnitEnum.MONTH.getCode());
                Date dataCircleTime = DateTimeUtil.updateDataCircleTime(dataIntervalUnit, value, nextStartTime);
                dataCircle = DateTimeUtil.formatDataCircle(dataCircleTime, dataIntervalUnit);
            }
            //替换原来的动态表规则
            String targetTableName = importRuleTable.getTargetTableName();
            targetTableName = targetTableName.substring(0, targetTableName.lastIndexOf("_"));

            content = content.replace("TARGET_TABLE",
                    importRuleTable.getTargetSchema() + "." + targetTableName + "_" + dataCircle);
        } else {
            content = content.replace("TARGET_TABLE",
                    importRuleTable.getTargetSchema() + "." + importRuleTable.getTargetTableName());
        }
        //分隔符
        content = content.replace("SEPARATOR", importRule.getSeperator());
        //导入方式
        if (importRule.getLoadType().equals(String.valueOf(LoadTypeEnum.APPEND.getCode()))) {
            content = content.replace("LOAD_TYPE", LoadTypeEnum.APPEND.getMsg());
        } else if (importRule.getLoadType().equals(String.valueOf(LoadTypeEnum.TRUNCATE.getCode()))) {
            content = content.replace("LOAD_TYPE", LoadTypeEnum.TRUNCATE.getMsg());
        }
        //插入导入字段
        StringBuilder ctlFileContent = new StringBuilder(content);
        //对NUMBER、VARCHAR2进行类型转换
        String targetColumnsStr = this.convertColumnType(targetColumnList);
        //添加到ctlFileContent
        ctlFileContent.insert(content.indexOf('(') + 1, "\n" + targetColumnsStr);
        return ctlFileContent.toString();
    }

    public String convertColumnType(String targetColumnList) {
        String[] targetColumns = targetColumnList.split(",");
        for (int i = 0; i < targetColumns.length; i++) {
            String targetColumn = targetColumns[i];
            if (targetColumn.contains("number") || targetColumn.contains("NUMBER")) {
                targetColumns[i] = targetColumn.replaceAll("number|NUMBER", "CHAR");
            } else if (targetColumn.contains("varchar2") || targetColumn.contains("VARCHAR2")) {
                targetColumns[i] = targetColumn.replaceAll("varchar2|VARCHAR2", "CHAR");
            } else if (targetColumn.contains("INTERVAL")) {
                String targetColumnType = targetColumn.substring(targetColumn.indexOf("INTERVAL"));
                targetColumns[i] = targetColumn.replace(targetColumnType, "CHAR");
            } else if (targetColumn.contains("interval")) {
                String targetColumnType = targetColumn.substring(targetColumn.indexOf("INTERVAL"));
                targetColumns[i] = targetColumn.replace(targetColumnType, "CHAR");
            } else if (targetColumn.contains("NUMERIC") || targetColumn.contains("numeric")) {
                targetColumns[i] = targetColumn.replaceAll("NUMERIC|numeric", "CHAR");
            } else if (targetColumn.contains("varchar") || targetColumn.contains("VARCHAR")) {
                targetColumns[i] = targetColumn.replaceAll("varchar|VARCHAR", "CHAR");
            } else if (targetColumn.contains("timestamp with time zone") || targetColumn.contains("TIMESTAMP WITH TIME ZONE")) {
                targetColumns[i] = targetColumn.replaceAll("timestamp with time zone|TIMESTAMP WITH TIME ZONE", "TIMESTAMP");
            } else if (targetColumn.contains("timestamp with local time zone") || targetColumn.contains("TIMESTAMP WITH LOCAL TIME ZONE")) {
                targetColumns[i] = targetColumn.replaceAll("timestamp with local time zone|TIMESTAMP WITH LOCAL TIME ZONE", "TIMESTAMP");
            } else if (targetColumn.contains(" date") || targetColumn.contains(" DATE")) {
                targetColumns[i] = targetColumn.replaceAll("\\sdate|\\sDATE", " TIMESTAMP");
            } else if (targetColumn.contains("bpchar") || targetColumn.contains("BPCHAR")) {
                targetColumns[i] = targetColumn.replaceAll("bpchar|BPCHAR", "CHAR");
            }
        }
        targetColumnList = Arrays.toString(targetColumns);
        return targetColumnList.substring(1, targetColumnList.length() - 1);
    }
}